#!/usr/bin/python

import cgi
import logging

from google.appengine.api import users
from google.appengine.ext import db
from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app

from hips import datastore
from hips import serialization
from hips import translator
from hips.handlers import query
from hips.scheduling import schedule


class ModelWriteHandler(webapp.RequestHandler):
  """Base class for all handlers that write models.

  Many models can be edited and created using simple logic. These models
  can just use DefaultModelWriteHandlers. Some models, such as schedules
  and schedule solutions, need special handling for creation (and possibly
  editing later on). These special models will have different handlers
  for creation and editing.

  Some of these handlers will create a complex hierarchy of models, but the
  edit handlers just need to rely on default model edit behavior."""

  def post(self):
    """Responds to requests for writing models to the store."""
    logging.info(self.request.body)
    models = self.CreateModels(self.request.body)
    for model in models:
      model.put()
    serialized_model = serialization.WriteModelListToString(models)
    logging.info("%s received write request with contents %s" %
        (self.__class__.__name__, serialized_model))
    self.response.out.write(serialized_model)

  def CreateModels(self, request_str):
    """Creates models to save from request string."""
    pass


class DefaultModelWriteHandler(ModelWriteHandler):
  """Most models can just get by relying on default serialization."""

  def CreateModels(self, request_str):
    """Creates models to save from request string."""
    return serialization.ReadModelListFromString(request_str)


class ScheduleCreationHandler(ModelWriteHandler):
  """Schedule creation is a special case."""

  def CreateModels(self, request_str):
    """Creates Schedule models, with associated constraints and blocks."""
    # schedule_model will have institution and start_time
    schedule_model = serialization.ReadModelListFromString(request_str)[0]
    doctor_list = query.QueryForModels(
        "SELECT * FROM Doctor WHERE institution = :institution",
        {"institution": schedule_model.institution.key()}).All()
    hips_schedule = schedule.CreateScheduleStartingAtMonth(
        schedule_model.start_time)
    model_list = translator.CreateScheduleModels(hips_schedule,
        schedule_model, doctor_list)
    return model_list
